package com.leoman.userapi.service.impl;

import com.leoman.city.dao.CityDao;
import com.leoman.city.entity.City;
import com.leoman.common.service.impl.GenericManagerImpl;
import com.leoman.creator.dao.CreatorDao;
import com.leoman.creator.dao.CreatorImageDao;
import com.leoman.creator.entity.Creator;
import com.leoman.creator.entity.CreatorImage;
import com.leoman.entity.Configue;
import com.leoman.entity.Constant;
import com.leoman.exception.*;
import com.leoman.indexapi.service.UserTaskApiService;
import com.leoman.message.entity.vo.MessageVo;
import com.leoman.post.dao.CommentPraiseDao;
import com.leoman.post.dao.PostBaseDao;
import com.leoman.post.dao.PostCommentDao;
import com.leoman.post.dao.PostImageDao;
import com.leoman.post.entity.CommentPraise;
import com.leoman.post.entity.PostBase;
import com.leoman.post.entity.PostComment;
import com.leoman.post.entity.PostImage;
import com.leoman.post.entity.vo.PostImageVo;
import com.leoman.postapi.service.PostService;
import com.leoman.sensitivewords.dao.SensitiveWordsDao;
import com.leoman.sensitivewords.entity.SensitiveWords;
import com.leoman.systemsetting.entity.LimitWords;
import com.leoman.systemsetting.entity.UserTask;
import com.leoman.user.dao.*;
import com.leoman.user.entity.*;
import com.leoman.user.entity.vo.UserCollectVo;
import com.leoman.user.entity.vo.UserInfoPlusVo;
import com.leoman.user.entity.vo.UserInvitedVo;
import com.leoman.user.entity.vo.UserRegisterVo;
import com.leoman.userapi.service.UserInfoService;
import com.leoman.userapi.service.UserIntegralService;
import com.leoman.userchange.dao.UserChangeDao;
import com.leoman.userchange.entity.UserChange;
import com.leoman.utils.DateUtils;
import com.leoman.utils.ImageUtil;
import com.leoman.vcode.VcodeService;
import com.leoman.work.dao.WorkDao;
import com.leoman.work.entity.Work;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 用户接口实现类
 * Created by 涂奕恒 on 2016/6/12.
 */
@Service
public class UserInfoServiceImpl extends GenericManagerImpl<UserInfo, UserInfoDao> implements UserInfoService {

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private UserLoginDao userLoginDao;

    @Autowired
    private PostCommentDao postCommentDao;

    @Autowired
    private PostService postService;

    @Autowired
    private PostImageDao postImageDao;

    @Autowired
    private UserAttentionDao userAttentionDao;

    @Autowired
    private UserCollectDao userCollectDao;

    @Autowired
    private VcodeService vcodeService;

    @Autowired
    private CreatorDao creatorDao;

    @Autowired
    private CreatorImageDao creatorImageDao;

    @Autowired
    private CityDao cityDao;

    @Autowired
    private UserIntegralDao userIntegralDao;

    @Autowired
    private UserChangeDao userChangeDao;

    @Autowired
    private PostBaseDao postBaseDao;

    @Autowired
    private UserIntegralService userIntegralService;

    @Autowired
    private CommentPraiseDao commentPraiseDao;

    @Autowired
    private UserSignDao userSignDao;

    @Autowired
    private UserInvitedDao userInvitedDao;

    @Autowired
    private UserInvitedDetailDao userInvitedDetailDao;

    @Autowired
    private SensitiveWordsDao sensitiveWordsDao;

    @Autowired
    private UserTaskApiService userTaskApiService;

    @Autowired
    private WorkDao workDao;

    @Autowired
    private UserCheckDao userCheckDao;

    @Override
    public UserLogin registerCheck(UserRegisterVo urv) throws CodeErrorException {
        if (!vcodeService.validate(urv.getMobile(), urv.getCode())) {
            throw new CodeErrorException();
        }

        UserLogin userlogin = userLoginDao.findByUsername(urv.getMobile());
        if (userlogin != null) {
            return null;
        }
        userlogin = new UserLogin();
        userlogin.setUsername(urv.getMobile());
        userlogin.setPassword(urv.getPassword());
        userLoginDao.save(userlogin);
        return userlogin;
    }

    @Transactional
    @Override
    public UserInfo register(UserRegisterVo urv) throws UserExistException, CodeErrorException, UserNicknameExistException, SensitiveWordExistException {
        // 判断是否包含关键词
        List<SensitiveWords> sensitiveWordsList = sensitiveWordsDao.findByContentPlus("%" + urv.getNickname() + "%");
        if (null != sensitiveWordsList && sensitiveWordsList.size() > 0) {
            throw new SensitiveWordExistException();
        }
        UserLogin userlogin = registerCheck(urv);
        if (userlogin == null) {
            throw new UserExistException();
        }
        if (null != userInfoDao.findOneByNickname(urv.getNickname())) {
            throw new UserNicknameExistException();
        }
        UserInfo userInfo = new UserInfo();
        userInfo.setUserLogin(userlogin);
        userInfo.setMobile(userlogin.getUsername());
        userInfo.setNickname(urv.getNickname());
        userInfo.setPassword(urv.getPassword());

        this.save(userInfo);

        // 注册成功获得5馒头
        userIntegralService.changeCoin(userInfo, "注册成功", 5);

        userTaskApiService.setDefaultTask(userInfo.getId());

        return userInfo;
    }

    @Override
    public UserInfo findOne(Long userId) throws UserNotFindException {
        if (null == userId) {
            throw new UserNotFindException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        return userInfo;
    }

    @Override
    public UserInfo findUserLoginById(Long userId) throws UserNotFindException {
        return userInfoDao.findOneByUserId(userId);
    }

    @Override
    public UserInfo findOne(Long sourceId, Long userId, Integer type) throws UserNotFindException {
        if (null == sourceId) {
            throw new UserNotFindException();
        }

        UserInfo userInfo = userInfoDao.findOne(sourceId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        if (null != userId) {
            UserAttention tempUserAttention = userAttentionDao.findOneInfo(userId, sourceId);
            if (null == tempUserAttention || tempUserAttention.getStatus() == 1) {
                userInfo.setIsAttention(1);
            } else {
                userInfo.setIsAttention(0);
            }
        }

        // 查询收藏数
        List<UserCollect> collectList = userCollectDao.findListByUserId(sourceId);
        Integer collectCount = 0;
        Work work;
        PostBase postBase;

        for (UserCollect userCollect : collectList) {
            switch (userCollect.getType()) {
                case 1:
                    // 视频
                case 2:
                    // 小说
                case 3:
                    // 漫画
                    work = workDao.findOne(userCollect.getSourceId());
                    if (null != work && work.getStatus().equals(0)) {
                        collectCount++;
                    }
                    break;
                case 4:
                    // 帖子
                    postBase = postBaseDao.findOne(userCollect.getSourceId());
                    if (null != postBase && !postBase.getDeleteStatus().equals(1)) {
                        collectCount++;
                    }
                    break;
            }
        }

        userInfo.setNum(collectCount);

        // 查询粉丝数
        userInfo.setFuns(Long.parseLong(userAttentionDao.iFindFans(sourceId).size() + ""));

        // 查询关注数
        userInfo.setFocus(Long.parseLong(userAttentionDao.findListByUserId(sourceId).size() + ""));

        // 查询是否已签到
        userInfo.setIsSign(checkSign(sourceId));

        // 查询连续签到天数
        UserSign userSign = userSignDao.findOneByUserId(sourceId);
        userInfo.setDays(null == userSign ? 0 : userSign.getDays());

        userInfo.setPlayType(Constant.PLAY_TYPE_001);

        // 查询升级到下一级所需经验
        userInfo.setLevelUpIntegral(userIntegralService.getMoreIntegral(userInfo.getIntegral()));

        // 查询是否申请认证为主创
        UserCheck userCheck = userCheckDao.findOneByUserId(sourceId);

        if (null == userCheck) {
            userInfo.setIsCheck(null);
        } else {
            userInfo.setIsCheck(userCheck.getStatus());
        }

        return userInfo;
    }

    /**
     * 检测是否签到
     */
    private Integer checkSign(Long userId) {
        UserSign userSign = userSignDao.findOneByUserId(userId);

        if (null == userSign) {
            return 1;
        } else {
            try {
                if (userSign.getSingDate().equals(DateUtils.longToString(System.currentTimeMillis(), "yyyy-MM-dd"))) {
                    return 0;
                } else {
                    return 1;
                }
            } catch (ParseException e) {
                e.printStackTrace();
                return 1;
            }
        }
    }

    @Override
    public UserInfoPlusVo findCreatorInfo(Long sourceId, Long userId) throws ParamsErrorException, CreatorNotFindException {
        if (null == sourceId) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(sourceId);
        if (null == userInfo || null == userInfo.getCreator()) {
            throw new CreatorNotFindException();
        }

        Creator creator = userInfo.getCreator();

        UserInfoPlusVo userInfoPlusVo = new UserInfoPlusVo();
        userInfoPlusVo.setId(creator.getId());
        userInfoPlusVo.setUserId(userInfo.getId());
        userInfoPlusVo.setName(userInfo.getNickname());
        userInfoPlusVo.setCover(StringUtils.isNotEmpty(creator.getCoverUrl()) ? ImageUtil.clearUploadUrl(creator.getCoverUrl()) : "");
        userInfoPlusVo.setAvater(StringUtils.isNotEmpty(userInfo.getAvater()) ? ImageUtil.clearUploadUrl(userInfo.getAvater()) : "");
        userInfoPlusVo.setProvince(null != creator.getProvince() ? creator.getProvince().getName() : "");
        userInfoPlusVo.setCity(null != creator.getCity() ? creator.getCity().getName() : "");
        userInfoPlusVo.setDescription(creator.getDescription());
        userInfoPlusVo.setLevel(userInfo.getLevel());

        // 查询粉丝数
        userInfoPlusVo.setFans(userAttentionDao.iFindFans(sourceId).size());

        // 查询关注数
        userInfoPlusVo.setFocus(userAttentionDao.findListByUserId(sourceId).size());

        if (null != userId) {
            UserAttention tempUserAttention = userAttentionDao.findOneInfo(userId, userInfo.getId());
            if (null == tempUserAttention || tempUserAttention.getStatus() == 1) {
                userInfoPlusVo.setIsAttention(1);
            } else {
                userInfoPlusVo.setIsAttention(0);
            }
        }

        // 查询是否已签到
        userInfo.setIsSign(checkSign(userId));

        userInfoPlusVo.setStillList(getImageList(creatorImageDao.findList(creator.getId(), 0)));
        userInfoPlusVo.setLifeList(getImageList(creatorImageDao.findList(creator.getId(), 1)));
        userInfoPlusVo.setWeibo(creator.getWeibo());
        userInfoPlusVo.setFanClub(creator.getExperience());

        return userInfoPlusVo;
    }

    /**
     * 获取生活照和剧照
     */
    private List<PostImageVo> getImageList(List<CreatorImage> imageList) {
        List<PostImageVo> list = new ArrayList<>();
        PostImageVo postImageVo;

        for (CreatorImage creatorImage : imageList) {
            postImageVo = new PostImageVo();
            postImageVo.setId(creatorImage.getId());
            postImageVo.setUrl(ImageUtil.clearUploadUrl(creatorImage.getSuolue()));

            list.add(postImageVo);
        }

        return list;
    }

    @Override
    @Transactional
    public void attention(Long userId, Long sourceId, Integer type) throws ParamsErrorException, UserNotFindException, CreatorNotFindException, AttentionExistException, AttentionNotFindException {
        if (null == userId || null == sourceId || null == type) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        // 获取目标用户信息
        UserInfo sourceUserInfo = userInfoDao.findOne(sourceId);
        if (null == sourceUserInfo) {
            throw new UserNotFindException();
        }

        UserAttention userAttention = userAttentionDao.findOneInfo(userId, sourceId);

        // type  类型， 1：关注 2：取消关注
        if (type == 1) {
            if (null != userAttention && userAttention.getStatus() == 0) {
                throw new AttentionExistException();
            }

            if (null == userAttention) {
                // 关注
                userAttention = new UserAttention();
                userAttention.setUser(userInfo);
                userAttention.setSourceUser(sourceUserInfo);
                userAttention.setCreateDate(System.currentTimeMillis());
                userAttention.setStatus(0);
            } else {
                userAttention.setStatus(0);
            }

            // 用户增加关注数，被关注用户增加粉丝数
            userInfo.setFocus(userInfo.getFocus() + 1);
            sourceUserInfo.setFuns(sourceUserInfo.getFuns() + 1);
        } else {
            if (null == userAttention) {
                throw new AttentionNotFindException();
            }

            // 取消关注
            userAttention.setStatus(1);

            // 用户减少关注数，被关注用户减少粉丝数
            userInfo.setFocus(userInfo.getFocus() - 1);
            sourceUserInfo.setFuns(sourceUserInfo.getFuns() - 1);
        }

        userAttentionDao.save(userAttention);
        userInfoDao.save(userInfo);
        userInfoDao.save(sourceUserInfo);
    }

    @Override
    public List<UserCollectVo> findCollectListByUserId(Long userId) {
        // List<UserCollect> collectList = userCollectDao.findListByUserId(userId);
        // List<UserCollectVo> list = new ArrayList<>();
        // UserCollectVo userCollectVo;

        /*WorkVideoVo workVideoVo = null;
        WorkNovelVo workNovelVo = null;
        WorkComicVo workComicVo = null;
        PostBase postBase = null;*/

        /*try {
            for (UserCollect userCollect : collectList) {
                userCollectVo = new UserCollectVo();

                *//*switch (userCollect.getType()) {
                    case 1:
                        // 视频
                        workVideoVo = workService.findVideo(userCollect.getSourceId(), userId);
                        if (null == workVideoVo) {
                            continue;
                        }
                        userCollectVo.setId(workVideoVo.getId());
                        userCollectVo.setName(workVideoVo.getName());
                        userCollectVo.setAvater(Configue.getUploadUrl() + workVideoVo.getCover());
                        userCollectVo.setPlayNum(workVideoVo.getPlayNum());
                        userCollectVo.setBarrageNum(workVideoVo.getBarrageNum());
                        break;
                    case 2:
                        // 小说
                        workNovelVo = workService.findNovel(userCollect.getSourceId(), userId);
                        if (null == workNovelVo) {
                            continue;
                        }
                        userCollectVo.setId(workNovelVo.getId());
                        userCollectVo.setName(workNovelVo.getName());
                        userCollectVo.setAuthor(workNovelVo.getAuthor());
                        userCollectVo.setAvater(Configue.getUploadUrl() + workNovelVo.getCover());
                        userCollectVo.setDescription(workNovelVo.getDescription());
                        break;
                    case 3:
                        // 漫画
                        workComicVo = workService.findComic(userCollect.getSourceId(), userId);
                        if (null == workComicVo) {
                            continue;
                        }
                        userCollectVo.setId(workComicVo.getId());
                        userCollectVo.setName(workComicVo.getName());
                        userCollectVo.setAuthor(workComicVo.getAuthor());
                        userCollectVo.setAvater(Configue.getUploadUrl() + workComicVo.getCover());
                        userCollectVo.setPlayNum(workComicVo.getPlayNum());
                        userCollectVo.setUpdateTime(workComicVo.getUpdateTime());
                        break;
                }*//*

                list.add(userCollectVo);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }*/

        // return list;
        return null;
    }

    @Override
    public Page<PostBase> findCollectListByUserIdPost(Long userId, Integer pageNum, Integer pageSize) {
        Page<PostBase> page = postService.iPageByUserCollect(userId, pageNum, pageSize);

        List<PostImage> postImageList;
        for (PostBase postBase : page.getContent()) {
            if (postBase.getType().equals(Constant.POST_TYPE_003)) {
                postImageList = postImageDao.findList(postBase.getId(), postBase.getType());
                postBase.setAvater((null == postImageList || postImageList.size() == 0) ? "" : ImageUtil.clearUploadUrl(postImageList.get(0).getSuolue()));
            } else {
                postBase.setAvater(StringUtils.isNotEmpty(postBase.getSuolue()) ? ImageUtil.clearUploadUrl(postBase.getSuolue()) : "");
            }
            postBase.setAuthorName(postBase.getUserInfo().getNickname());
        }

        return page;
    }

    @Override
    public void collect(Long userId, Long sourceId, Integer type, Integer status) throws ParamsErrorException, UserNotFindException, CollectExistException, CollectNotFindException {
        if (null == userId || null == sourceId || null == type || null == status) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }
        userInfo = UserInfoServiceImpl.clearUploadPath(userInfo);

        List<UserCollect> userCollectList = userCollectDao.findListByParams(userId, sourceId, type);
        UserCollect userCollect = null;

        if (null != userCollectList && userCollectList.size() > 0) {
            userCollect = userCollectList.get(0);
        }

        // status  类型，1：收藏 2：取消收藏
        if (status == 1) {
            if (null != userCollect) {
                throw new CollectExistException();
            }

            // 收藏
            userCollect = new UserCollect();
            userCollect.setUserInfo(userInfo);
            userCollect.setSourceId(sourceId);
            userCollect.setType(type);

            userCollectDao.save(userCollect);
            /*if (type == 4) {
                // 发布的帖子被收藏可获得2个经验值
                PostBase postBase = postBaseDao.findOne(sourceId);
                if (null != postBase) {
                    userIntegralService.changeIntegral(postBase.getUserInfo(), "发布的帖子被收藏获得2个经验值", 2);
                }
            }*/
        } else {
            if (null == userCollect) {
                throw new CollectNotFindException();
            }

            userCollectDao.delete(userCollect);
        }
    }

    @Override
    public void praise(Long userId, Long sourceId, Integer type, Integer status) throws ParamsErrorException, UserSpeakErrorException, PraiseExistException, PraiseNotFindException {
        if (null == userId || null == sourceId || null == type) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (userInfo.getStatus().equals(Constant.USER_STATUS_GAG)) {
            throw new UserSpeakErrorException();
        }

        List<UserChange> userChangeList = userChangeDao.findListByParams(userId, sourceId, Constant.USER_CHANGE_TYPE_001);
        UserChange userChange = null;

        if (null != userChangeList && userChangeList.size() > 0) {
            userChange = userChangeList.get(0);
        }

        PostBase postBase = postBaseDao.findOne(sourceId);

        if (null == postBase) {
            throw new ParamsErrorException();
        }

        // 默认为点赞
        if (null == status || status == 1) {
            if (null != userChange) {
                throw new PraiseExistException();
            }

            userChange = new UserChange();
            userChange.setPostBase(postBase);
            userChange.setType(Constant.USER_CHANGE_TYPE_001);
            userChange.setContent(postBase.getContent());
            userChange.setUserInfo(userInfo);

            userChangeDao.save(userChange);

            // 增加点赞数
            postBase.setPraise(postBase.getPraise() + 1);

            // 发布的帖子被点赞获得2经验值
            /*if (type.equals(Constant.POST_TYPE_003)) {
                userInfo = postBaseDao.findOne(sourceId).getUserInfo();
                userIntegralService.changeIntegral(userInfo, "发布的帖子被点赞获得2经验值", 2);
            }*/

            // 进行每日点赞任务
            userTaskApiService.finishTask(userId, Constant.USER_TASK_TYPE_002, false);

            // 点赞其他帖子可获得5经验值，每日最多获得10经验值
            if (!postBase.getUserInfo().getId().equals(userId)) {
                UserTask userTask = userTaskApiService.findInfoByUserIdAndType(userId, Constant.USER_TASK_TYPE_002);
                if (userTask.getCount() <= 5) {
                    userIntegralService.changeIntegral(userInfo, "点赞其他帖子可获得10经验值", 10);
                }
            }

            if (!userInfo.getIsCreator().equals(Constant.IF_CREATOR_NO)) {
                postBase.setIsCreator(Constant.IF_CREATOR_YES);
            }
        } else {
            if (null == userChange) {
                throw new PraiseNotFindException();
            }
            userChangeDao.delete(userChange);

            // 减少点赞数
            postBase.setPraise(postBase.getPraise() - 1);
        }

        postBaseDao.save(postBase);
    }

    @Override
    public void praise2(Integer isDetail, Long userId, Long sourceId, Integer type, Integer status) throws ParamsErrorException, UserNotFindException, PraiseExistException, PraiseNotFindException, UserStatusErrorException {
        if (null == userId || null == sourceId || null == type) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = getUserInfo(userInfoDao, userId);

        CommentPraise commentPraise = commentPraiseDao.findOneByParams(sourceId, userId, type, isDetail);

        // 默认为点赞
        if (null == status || status == 1) {
            if (null != commentPraise) {
                throw new PraiseExistException();
            }

            commentPraise = new CommentPraise();
            commentPraise.setCommentId(sourceId);
            commentPraise.setType(type);
            commentPraise.setUserInfo(userInfo);
            commentPraise.setIsDetail(isDetail);

            commentPraiseDao.save(commentPraise);
        } else {
            if (null == commentPraise) {
                throw new PraiseNotFindException();
            }
            commentPraiseDao.delete(commentPraise);
        }
    }

    @Override
    public void modifyCreatorInfo(Long creatorId, Long cityId, String description, String weibo, String experience) throws ParamsErrorException, CreatorNotFindException {
        if (null == creatorId) {
            throw new ParamsErrorException();
        }

        Creator creator = creatorDao.findOne(creatorId);
        if (null == creator) {
            throw new CreatorNotFindException();
        }

        try {
            if (null != cityId) {
                City city = cityDao.findOne(cityId);
                creator.setCity(city);
                creator.setProvince(city.getProvince());
            }

            if (StringUtils.isNotEmpty(description)) {
                creator.setDescription(description);
            }

            if (StringUtils.isNotEmpty(weibo)) {
                creator.setWeibo(weibo);
            }

            if (StringUtils.isNotEmpty(experience)) {
                creator.setExperience(experience);
            }

            creatorDao.save(creator);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void binding(Long userId, Integer type, String openId, String nickname) throws UserNotFindException, ThirdExistException {
        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        List<UserInfo> list;

        switch (type) {
            case 1:
                if (StringUtils.isNotEmpty(openId) && StringUtils.isNotEmpty(nickname)) {
                    list = userInfoDao.findOneByWeixin(openId);
                    if (null != list && list.size() > 0) {
                        throw new ThirdExistException();
                    }
                }

                userInfo.setWeixin(openId);
                userInfo.setWeixinNickname(nickname);
                break;
            case 2:
                if (StringUtils.isNotEmpty(openId) && StringUtils.isNotEmpty(nickname)) {
                    list = userInfoDao.findOneByWeixin(openId);
                    if (null != list && list.size() > 0) {
                        throw new ThirdExistException();
                    }
                }

                userInfo.setWeibo(openId);
                userInfo.setWeiboNickname(nickname);
                break;
            case 3:
                if (StringUtils.isNotEmpty(openId) && StringUtils.isNotEmpty(nickname)) {
                    list = userInfoDao.findOneByWeixin(openId);
                    if (null != list && list.size() > 0) {
                        throw new ThirdExistException();
                    }
                }

                userInfo.setQq(openId);
                userInfo.setQqNickname(nickname);
                break;
        }

        userInfoDao.save(userInfo);
    }

    @Override
    @Transactional
    public void bindingMobile(Long userId, String mobile, String code, String password, String nickname, String openId, Integer type) throws ParamsErrorException, UserNotFindException, CodeErrorException, MobileExistException, UserNicknameExistException, SensitiveWordExistException {
        if (null == userId || StringUtils.isEmpty(mobile) || StringUtils.isEmpty(code) || StringUtils.isEmpty(password) || StringUtils.isEmpty(nickname) || StringUtils.isEmpty(openId) || null == type) {
            throw new ParamsErrorException();
        }

        List<SensitiveWords> sensitiveWordsList = sensitiveWordsDao.findByContentPlus("%" + nickname + "%");
        if (null != sensitiveWordsList && sensitiveWordsList.size() > 0) {
            throw new SensitiveWordExistException();
        }

        UserInfo tempInfo = userInfoDao.findOneByNickname(nickname);
        if (null != tempInfo && !tempInfo.getId().equals(userId)) {
            throw new UserNicknameExistException();
        }

        UserInfo userInfo = userInfoDao.findOneByMobile(mobile);

        if (!StringUtils.isNotEmpty(code)) {
            throw new CodeErrorException();
        }

        if (!vcodeService.validate(mobile, code)) {
            throw new CodeErrorException();
        }

        List<UserInfo> list;

        // 如果手机号不为空，则表示已经有该手机号的用户，此时绑定该第三方信息到该用户上
        // 如果没有，新增一条用户信息，同时绑定该第三方信息
        if (null == userInfo) {
            UserLogin userLogin = new UserLogin();
            userLogin.setUsername(mobile);
            userLogin.setPassword(password);
            userLogin.setCreateDate(System.currentTimeMillis());

            userLoginDao.save(userLogin);

            userInfo = new UserInfo();
            userInfo.setUserLogin(userLogin);
        }

        userInfo.setMobile(mobile);
        userInfo.setNickname(nickname);
        userInfo.setPassword(password);

        switch (type) {
            case 1:
                list = userInfoDao.findOneByWeixin(openId);
                if (null == list || list.size() == 0) {
                    userInfo.setWeixin(openId);
                    userInfo.setWeixinNickname(nickname);
                }
                break;
            case 2:
                list = userInfoDao.findOneByWeibo(openId);
                if (null == list || list.size() == 0) {
                    userInfo.setWeibo(openId);
                    userInfo.setWeiboNickname(nickname);
                }
                break;
            case 3:
                list = userInfoDao.findOneByQQ(openId);
                if (null == list || list.size() == 0) {
                    userInfo.setQq(openId);
                    userInfo.setQqNickname(nickname);
                }
                break;
            default:
                throw new ParamsErrorException();
        }

        userInfoDao.save(userInfo);
    }

    @Override
    public Page<UserIntegral> integralPage(Long userId, Integer pageNum, Integer pageSize) throws UserNotFindException {
        if (null == pageNum) {
            pageNum = 1;
        }
        if (null == pageSize) {
            pageSize = Constant.PAGE_DEF_SIZE;
        }
        return userIntegralDao.pageByUserId(userId, new PageRequest(pageNum - 1, pageSize));
    }

    @Override
    public List<UserInfo> findOneByWeixin(String weixin) {
        return userInfoDao.findOneByWeixin(weixin);
    }

    @Override
    public List<UserInfo> findOneByWeibo(String weibo) {
        return userInfoDao.findOneByWeibo(weibo);
    }

    @Override
    public List<UserInfo> findOneByQQ(String qq) {
        return userInfoDao.findOneByQQ(qq);
    }

    @Override
    public UserInfo findOneByNickname(String nickname) {
        return userInfoDao.findOneByNickname(nickname);
    }

    @Override
    public Page<MessageVo> pageMessage(Long userId, Integer pageNum, Integer pageSize) {
        List<PostComment> postCommentList = postCommentDao.iFindListByToUserId(userId);

        for (PostComment postComment : postCommentList) {
            if (postComment.getIsRead().equals(Constant.MESSAGE_READ_STATUS_YES)) {
                continue;
            }
            postComment.setIsRead(Constant.MESSAGE_READ_STATUS_YES);
            postCommentDao.save(postComment);
        }

        final Page<PostComment> postCommentPage = postCommentDao.pageByToUserId(userId, new PageRequest(pageNum - 1, pageSize));
        return new Page<MessageVo>() {
            @Override
            public int getNumber() {
                return postCommentPage.getNumber();
            }

            @Override
            public int getSize() {
                return postCommentPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return postCommentPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return postCommentPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return postCommentPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return postCommentPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return postCommentPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return postCommentPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return postCommentPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return postCommentPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return postCommentPage.previousPageable();
            }

            @Override
            public Iterator<MessageVo> iterator() {
                final Iterator<PostComment> postCommentIterator = postCommentPage.iterator();
                return new Iterator<MessageVo>() {
                    @Override
                    public boolean hasNext() {
                        return postCommentIterator.hasNext();
                    }

                    @Override
                    public MessageVo next() {
                        return getMessageVo(postCommentIterator.next());
                    }
                };
            }

            @Override
            public List<MessageVo> getContent() {
                List<PostComment> postCommentList = postCommentPage.getContent();
                List<MessageVo> list = new ArrayList<>();

                for (PostComment postComment : postCommentList) {
                    list.add(getMessageVo(postComment));
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return postCommentPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return postCommentPage.getSort();
            }
        };
    }

    @Override
    public void share(Long userId) throws UserNotFindException, UserStatusErrorException {
        getUserInfo(userInfoDao, userId);

        UserInvited userInvited = userInvitedDao.findOneByUserId(userId);
        if (null == userInvited) {
            userInvited = new UserInvited();
            userInvited.setUser(userInfoDao.findOne(userId));
            userInvited.setCoin(0);
            userInvited.setTotalCoin(0);
            userInvited.setCount(0);
            userInvited.setIsShare(1);
        } else {
            if (userInvited.getIsShare() == 0) {
                userInvited.setIsShare(1);
            }
        }
        userInvitedDao.save(userInvited);

        // 进行每日分享帖子任务
        userTaskApiService.finishTask(userId, Constant.USER_TASK_TYPE_005, false);
    }

    /**
     * 检测用户状态
     */
    public static UserInfo getUserInfo(UserInfoDao userInfoDao, Long userId) throws UserNotFindException, UserStatusErrorException {
        UserInfo userInfo = userInfoDao.findOne(userId);
        if (null == userInfo) {
            throw new UserNotFindException();
        }

        if (userInfo.getStatus().equals(Constant.USER_STATUS_FREEZE)) {
            throw new UserStatusErrorException();
        }

        return userInfo;
    }

    @Override
    @Transactional
    public Integer invited(Long userId, String nickname, String mobile) throws ParamsErrorException, UserNotFindException, InvitedErrorException, InvitedCountErrorException, InvitedUserExistException, UserStatusErrorException {
        if (null == userId || StringUtils.isEmpty(nickname) || StringUtils.isEmpty(mobile)) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = getUserInfo(userInfoDao, userId);

        UserInfo sourceUser = userInfoDao.findOneByMobile(mobile);
        if (null == sourceUser || !sourceUser.getNickname().equals(nickname)) {
            throw new UserNotFindException();
        }

        if (sourceUser.getCreateDate() <= userInfo.getCreateDate()) {
            throw new InvitedErrorException();
        }

        UserInvited userInvited = userInvitedDao.findOneByUserId(userId);
        if (null == userInvited) {
            userInvited = new UserInvited();
            userInvited.setUser(userInfo);
            userInvited.setCoin(Constant.DEFAULT_INVITED_COIN);
            userInvited.setTotalCoin(Constant.DEFAULT_INVITED_COIN);
            userInvited.setCount(1);
            userInvited.setIsShare(0);
        } else {
            userInvited.setCoin(Constant.DEFAULT_INVITED_COIN);
            userInvited.setTotalCoin(userInvited.getTotalCoin() + Constant.DEFAULT_INVITED_COIN);
            userInvited.setCount(userInvited.getCount() + 1);
        }

        // 检测是否已经邀请过，如果已经邀请，则不可重复邀请
        UserInvitedDetail userInvitedDetail = userInvitedDetailDao.findOneBySourceUserId(sourceUser.getId());
        if (null != userInvitedDetail) {
            throw new InvitedUserExistException();
        }

        userInvitedDao.save(userInvited);

        // 保存邀请记录
        userInvitedDetail = new UserInvitedDetail();
        userInvitedDetail.setUser(userInfo);
        userInvitedDetail.setSourceUser(sourceUser);
        userInvitedDetail.setCreateDate(System.currentTimeMillis());

        userInvitedDetailDao.save(userInvitedDetail);

        userIntegralService.changeCoin(userInfo, "邀请用户注册获取" + Constant.DEFAULT_INVITED_COIN + "个馒头", Constant.DEFAULT_INVITED_COIN);

        return userInvited.getTotalCoin();
    }

    @Override
    @Transactional
    public UserInvitedVo invitedInfo(Long userId) throws UserNotFindException, UserStatusErrorException {
        UserInfo userInfo = getUserInfo(userInfoDao, userId);

        UserInvited userInvited = userInvitedDao.findOneByUserId(userId);

        if (null != userInvited) {
            UserInvitedVo userInvitedVo = new UserInvitedVo();
            userInvitedVo.setIsShare(userInvited.getIsShare());
            userInvitedVo.setCoin(userInvited.getCoin());
            userInvitedVo.setTotalCoin(userInvited.getTotalCoin());

            return userInvitedVo;
        } else {
            userInvited = new UserInvited();
            userInvited.setUser(userInfo);
            userInvited.setIsShare(0);
            userInvited.setCoin(0);
            userInvited.setTotalCoin(0);
            userInvited.setCount(0);
            userInvitedDao.save(userInvited);

            UserInvitedVo userInvitedVo = new UserInvitedVo();
            userInvitedVo.setIsShare(0);
            userInvitedVo.setCoin(0);
            userInvitedVo.setTotalCoin(0);

            return userInvitedVo;
        }
    }

    @Override
    public Integer sendPostCount() {
        List<LimitWords> list = userInfoDao.findLimitList();

        if (null != list && list.size() > 0) {
            return list.get(0).getNum();
        }

        return 200;
    }

    @Override
    public String replaceContent(String content) {
        if (StringUtils.isEmpty(content)) {
            return content;
        }
        List<SensitiveWords> sensitiveWordsList = sensitiveWordsDao.findAll();
        for (SensitiveWords sensitiveWords : sensitiveWordsList) {
            content = content.replace(sensitiveWords.getWords(), "***");
        }

        return content;
    }

    @Override
    public UserInfo getUserInfo(Long userId) throws UserNotFindException, UserStatusErrorException {
        return getUserInfo(userInfoDao, userId);
    }

    @Override
    public void sendCheck(Long userId, String userName, String profession, String mobile, String description, String reasonContent) throws ParamsErrorException, UserSpeakErrorException, UserSendCheckExistException {
        if (null == userId || StringUtils.isBlank(userName) || StringUtils.isBlank(profession) || StringUtils.isBlank(mobile) || StringUtils.isBlank(description) || StringUtils.isBlank(reasonContent)) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);

        if (userInfo.getStatus().equals(Constant.USER_STATUS_GAG)) {
            throw new UserSpeakErrorException();
        }

        UserCheck userCheck = userCheckDao.findOneByUserId(userId);

        if (null != userCheck) {
            throw new UserSendCheckExistException();
        }

        userCheck = new UserCheck();
        userCheck.setUserId(userId);
        userCheck.setUserName(userName);
        userCheck.setProfession(profession);
        userCheck.setMobile(mobile);
        userCheck.setDescription(description);
        userCheck.setReasonContent(reasonContent);
        userCheck.setStatus(0);

        userCheckDao.save(userCheck);
    }

    public static UserInfo clearUploadPath(UserInfo userInfo) {
        if (null == userInfo || StringUtils.isEmpty(userInfo.getAvater())) {
            return userInfo;
        }
        // 获取用户头像
        String avater = userInfo.getAvater().replaceAll(Configue.getUploadUrls(), "");
        if (!avater.contains("http")) {
            userInfo.setAvater(Configue.getUploadUrls() + avater);
        } else {
            userInfo.setAvater(avater);
        }

        return userInfo;
    }

    private MessageVo getMessageVo(PostComment postComment) {
        MessageVo messageVo = new MessageVo();
        UserInfo userInfo = userInfoDao.findOne(postComment.getFromUser().getId());
        userInfo = UserInfoServiceImpl.clearUploadPath(userInfo);
        PostBase postBase;
        UserInfo postUser;
        PostComment postComment1;

        messageVo.setId(postComment.getId());
        messageVo.setUserId(userInfo.getId());
        messageVo.setName(userInfo.getNickname());
        messageVo.setAvater(userInfo.getAvater());
        messageVo.setContent(postComment.getContent());
        messageVo.setSourceId(postComment.getPostBase().getId());
        messageVo.setSourceType(postComment.getType());
        if (postComment.getType().equals(Constant.POST_TYPE_003)) {
            postBase = postComment.getPostBase();
            postUser = postBase.getUserInfo();
            postUser = UserInfoServiceImpl.clearUploadPath(postUser);

            messageVo.setSourceName(postBase.getContent());
            messageVo.setSourceAvater(postUser.getAvater());
            messageVo.setSourceAuthor(postUser.getNickname());
        }

        if (null != postComment.getToPostCommentId()) {
            postComment1 = postCommentDao.findOne(postComment.getToPostCommentId());
            postBase = postComment1.getPostBase();
            messageVo.setReplyContent(postComment1.getContent());
            if (postComment1.getType().equals(Constant.POST_TYPE_003)) {
                messageVo.setSourceContent(postBase.getContent());
            } else {
                messageVo.setSourceContent(postBase.getName());
            }
        }
        messageVo.setCreateDate(postComment.getCreateDate());

        // 将消息读取状态修改为已读状态
        // postComment.setIsRead(Constant.MESSAGE_READ_STATUS_YES);
        // postCommentDao.save(postComment);

        return messageVo;
    }
}
